#include "../lib/plandwriter.hpp"
#include <boost/lexical_cast.hpp>
#include <iostream>
#include <fstream>

using namespace std;

static void hostMapHelper(vector < vector<Node*> > &hostMap, Node* n, int *id)
{
    if(n->property("id") == "")
    {
        int pos = n->propertyAsInt("host");
        hostMap[pos].push_back(n);
        n->addProperty("id", boost::lexical_cast<string>(*id));
        (*id)++;
    }
    for(size_t i = 0; i< n->childeren_.size();i++)
    {
        hostMapHelper(hostMap,n->childeren_[i], id);
    }
}

bool PlandWriter::ExportPland(vector<std::string> hosts, Graph &g, std::string prefixDir)
{
    if(g.properties_.find("hosts") == g.properties_.end())
    {
        cout << "No 'hosts' property in the graph exiting" << endl;
        return false;
    }
    size_t numHosts = boost::lexical_cast<size_t>(g.properties_.at("hosts"));
    if(numHosts > hosts.size())
    {
        cout << "Not enought hosts to export to" << endl;
        return false;
    }
    Node* source = g.source();
    vector < vector<Node*> > hostMap;
    for(size_t i =0; i< numHosts;i++)
    {
        hostMap.push_back(vector<Node*>());
    }
    int id = 0;
    hostMapHelper(hostMap,source, &id);
    for(size_t i =0; i< numHosts;i++)
    {
        cout << "Host " << hosts[i] << ": ";
        for(size_t j =0; j< hostMap[i].size();j++)
        {
            cout << hostMap[i][j]->name_ << " ";
        }
        cout << endl;
    }
    int netNum = 0;
    for(size_t i =0; i< numHosts;i++)
    {
        std::string fname = prefixDir + "/" + hosts[i] + "chain.xml";
        ofstream out;
        out.open(fname.c_str(), ios::out |ios::trunc);
        if(!out.is_open())
        {
            cout << "Could not open " << fname << endl;
            return false;
        }
        out << "<?xml version=\"1.0\" ?>" << endl;
        out << "<pland>" << endl;
        for(size_t j =0; j< hostMap[i].size();j++)
        {
            Node* current = hostMap[i][j];
            out << "\t<plugin>" << endl;
            out << "\t\t<net> " << current->name_ << " </net>" << endl;
            out << "\t\t<path> " << current->property("lib") << " </path>" << endl;
            out << "\t\t<id> " << current->property("id") << " </id>" << endl;
            out << "\t</plugin>" << endl;
            for(size_t k = 0; k < current->childeren_.size(); k++)
            {
                out << "\t<queue>" << endl;
                out <<	"\t\t<net> Net "<< boost::lexical_cast<string>(netNum) <<" </net>" << endl;
                netNum++;
                if(std::find(hostMap[i].begin(), hostMap[i].end(), current->childeren_[k]) != hostMap[i].end())
                {
                    out << "\t\t<sink> " << current->childeren_[k]->property("id") << " </sink>" << endl;
                }
                out << "\t\t<source> " << current->property("id") << " </source>" << endl;
                out << "\t</queue>" << endl;
            }

            for(size_t k = 0; k < current->parrents_.size(); k++)
            {
                if(std::find(hostMap[i].begin(), hostMap[i].end(), current->parrents_[k]) == hostMap[i].end())
                {

                    out << "\t<queue>" << endl;
                    out <<	"\t\t<net> Net "<< boost::lexical_cast<string>(netNum) <<" </net>" << endl;
                    netNum++;
                    out << "\t\t<sink> " << current->property("id") << " </sink>" << endl;
                    out << "\t</queue>" << endl;
                }
            }

        }
        out << "</pland>" << endl;
    }
    return true;
}
